/* Orbas:
 *     A open source CORBA Specification implementation from Huihoo.
 *
 * Copyright 2002-2003 Huihoo.org, Inc. All Right Reserved.
 *
 * This software is licensed under LGPL license.
 * See terms of license at gnu.org.
 *
 * For more information, visit:
 *
 * http://www.huihoo.org/orbas
 */

package org.huihoo.orbas.rtutil.threadpool;

/**
 * <p>Description:
 * Subclass of PooledExecutor,add the RealtimeThread and Priority control.</p>
 * <p>[<a href="http://gee.cs.oswego.edu/dl/classes/EDU/oswego/cs/dl/util/concurrent/intro.html">
 *  Introduction to util.concurrent package.
 * </a>]
 * <p>Copyright (c) 2003</p>
 * <p>Company: <a href="http://www.huihoo.org/orbas">huihoo.org</a></p>
 * @author <a href="http://www.huihoo.org/~cocia">Cocia Lin(cocia@163.com)</a>
 * @see <a href="http://www.huihoo.org/orbas">http://www.huihoo.org/orbas</a>
 * @version 1.0
 */

import EDU.oswego.cs.dl.util.concurrent.Channel;
import EDU.oswego.cs.dl.util.concurrent.PooledExecutor;

public class RTPooledExecutor extends PooledExecutor {

	protected int priority;

	public RTPooledExecutor(Channel channel, int minPoolSize, int maxPoolSize,
			int priority) {
		super(channel, maxPoolSize);
		this.priority = priority;
		this.setMinimumPoolSize(minPoolSize);

	}

	protected void addThread(Runnable command) {
		Worker worker = new RTWorker(command);
		// change this line from the parent class.
		Thread thread = this.createRTThread(this.priority, command);
		//
		threads_.put(worker, thread);
		++poolSize_;
		thread.start();

	}

	/**
	 * Create the RealtimeThread.
	 * 
	 * @param priori
	 *            Priority Number.
	 * @param command
	 *            Run logic
	 * @return instance of RealtimeThread
	 */
	protected Thread createRTThread(int priori, Runnable command) {
		return new Thread(command);

	}

	public void execute(Runnable command) throws java.lang.InterruptedException {
		int curPriori = this.getCurrentThreadPriority();
		RTRunnable rtlogic = new RTRunnable(command, curPriori);
		//
		super.execute(rtlogic);
	}

	protected int getCurrentThreadPriority() {
		return 1;

	}

	protected int setCurrentThreadPriority(int prio) {
		return 1;
	}

	protected class RTWorker extends Worker {
		protected RTWorker(Runnable firstTask) {
			super(firstTask);
		}

		public void run() {
			try {
				Runnable task = firstTask_;
				firstTask_ = null;

				if (task != null) {
					task.run();
					task = null;
				}
				while ((task = getTask()) != null) {
					// Change current thread priority to the priority of task.
					RTRunnable rttask = (RTRunnable) task;

					int oldprio = setCurrentThreadPriority(rttask.getPriority());

					// run the task.
					task.run();
					task = null;
					rttask = null;
					// priority change back.
					setCurrentThreadPriority(oldprio);
				}
			} catch (InterruptedException ex) {
			} // fall through
			finally {
				workerDone(this);
			}
		}

	}

	/** Runnable with priority. */
	protected class RTRunnable implements Runnable {
		private int priority;
		private Runnable logic;

		protected RTRunnable(Runnable logic, int priority) {
			this.logic = logic;
			this.priority = priority;
		}

		public int getPriority() {
			return priority;
		}

		public void run() {
			logic.run();
		}
	}

}